package defectsim;

import repast.simphony.space.continuous.NdPoint;
import repast.simphony.space.grid.Grid;
import repast.simphony.space.grid.GridPoint;

public class ObserverAgent {
	

	

	private void percept() {
		
	}
	
	private void mentalUpdate() {

		
	}
	
	private void act() {
		
	}
	
	public void update(){
		percept();
		mentalUpdate();
		act();
	}
	
	@SuppressWarnings("unchecked")
	private void calculateElasticEnergy(){
		SimEnvironment env = SimEnvironment.getInstance();
		Material mat = env.getCurrentMaterial();
		int gridSize = env.getGridSize();
		double[][] elasticInteractionEnergy = new double[gridSize][gridSize];
		
		double spaceToGridScale = env.getSpaceLength() / env.getGridSize();

		double C = 2 * Math.PI * (1 - mat.getPoissonRatio());
		
		Grid grid = (Grid) env.getContext().getProjection(env.getGridName());
		for (int i = 0; i < grid.getDimensions().getWidth(); i++)
			for (int j = 0; j < grid.getDimensions().getHeight(); j++){
				Iterable<Dislocation> allAgents = grid.getObjects();
				double energy = 0.0;
				for (Object a : allAgents) {
					if (a instanceof Dislocation){
						Dislocation dis = (Dislocation)a;
						GridPoint gp = grid.getLocation(dis);
						double x1 = i * spaceToGridScale;
						double x2 = gp.getX() * spaceToGridScale;
						double y1 = j * spaceToGridScale;
						double y2 = gp.getY() * spaceToGridScale;
						double l = Util.calculateMICDistance(new NdPoint(x1, y1), new NdPoint(x2, y2), env.getSpaceLength()); 
						double angle = Util.calculateMICAngle(new NdPoint(x1, y1), new NdPoint(x2, y2), env.getSpaceLength()); 
						double bgVec = dis.getUnitBurgersVector() * mat.getBurgersVector();
						double A = (mat.getShearModulus() * bgVec * bgVec) / C;
						double e = A * (Math.cos(2 * angle) - l * 1000 / mat.getBurgersVector());
						energy += e;
					}
				}
				elasticInteractionEnergy[i][j] = energy;
			}
	}
	
	// Observer agent class is singleton
	private ObserverAgent(){

	}

	private static ObserverAgent _instance = null;

	static public ObserverAgent getInstance() {
		if(_instance == null) {
			_instance = new ObserverAgent();
		}
		return _instance;
	}
}
